import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:easy_chat_app/commons/ServerConfig.dart';
import 'package:easy_chat_app/commons/utils/TokenUtils.dart';
import 'package:easy_chat_app/commons/ws/AppWSMessage.dart';
import 'package:easy_chat_app/commons/ws/AppWSMessageProcessor.dart';
import 'package:logger/logger.dart';

typedef AppWSMessageProcessFunc = Future<void> Function(AppWSMessage message);

class WSWebsocketClient {
  static const String wsURL =
      "$ecWSProtocolType://$ecServerIpAddress:$ecServerPort/app/ws/notify";

  static Logger logger = Logger();

  static WebSocket? _webSocket;

  static final WSWebsocketClient instance =
      WSWebsocketClient._privateConstructor();

  static final Map<String, AppWSMessageProcessFunc>
      _appWSMessageProcessFuncMap = {"NewMsg": newMsgProcess};

  WSWebsocketClient._privateConstructor() {
    Timer.periodic(const Duration(seconds: 5), (timer) async {
      // logger.i("Websocket连接检测...");
      if (_webSocket?.readyState == WebSocket.open) {
        // logger.i("Websocket连接正常...");
        return;
      }
      if (TokenUtils.hasToken()) {
        await initWSConnect();
      }
    });
  }

  Future<void> initWSConnect() async {
    logger.i("WS连接初始化: $wsURL");
    if (TokenUtils.hasToken()) {
      HttpClient customClient = HttpClient();
      customClient.connectionTimeout = const Duration(seconds: 1);
      _webSocket = await WebSocket.connect(wsURL,
          customClient: customClient, headers: {"token": TokenUtils.token()});
      if (_webSocket?.readyState == WebSocket.open) {
        logger.i("WebSocket连接建立成功...");
      }
      _webSocket!.listen(_onReceive, onDone: () {
        logger.i("WebSocket连接关闭，重建连接...");
      });
    }
  }

  Future<void> closeWSConnect() async {
    logger.i("WSState:${_webSocket?.readyState}");
    if (_webSocket?.readyState == WebSocket.open) {
      logger.i("WebSocket连接关闭...");
      await _webSocket?.close();
    }
  }

  Future<void> sendWSMessage(AppWSMessage message) async {
    logger.i("message:$message");
    // _webSocket.readyState
    _webSocket!.add(message.toJsonStr());
  }

  static void _onReceive(data) async {
    logger.i("data: $data");
    if (data is String) {
      var jsonData = jsonDecode(data);
      AppWSMessage message = AppWSMessage.fromJson(jsonData);
      logger.i(message);
      AppWSMessageProcessFunc? func = _appWSMessageProcessFuncMap[message.type];
      if (func != null) {
        await func(message);
      } else {
        logger.e("未找到对应消息的处理方法: $message");
      }
    }
  }
}
